<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>备忘录</title>
    <link rel="stylesheet" href="../static/plugins/easymde.min.css">
    <script src="../static/plugins/easymde.min.js"></script>
    <script src="../static/plugins/marked.min.js"></script>
    <script src="../static/plugins/purify.min.js"></script>
    <link rel="stylesheet" href="../static/plugins/fontawesome-free-6.0.0-web/css/all.min.css">
    <link rel="stylesheet" href="../static/plugins/highlight.github.min.css">
    <link href="../static/fonts/googleapis-fonts.css" rel="stylesheet">
    <style>
        :root {
            --primary-color: #007AFF;
            --secondary-color: #5856D6;
            --background-color: #F5F7F9;
            --card-background: #FFFFFF;
            --text-primary: #1D1D1F;
            --text-secondary: #86868B;
            --border-color: #E4E4E7;
            --success-color: #34C759;
            --warning-color: #FF9500;
            --error-color: #FF3B30;
            --sidebar-width: 280px;
            --container-max-width: 1400px;
            --border-radius: 12px;
            --shadow: 0 4px 24px rgba(0, 0, 0, 0.06);
        }

        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        body {
            font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
            line-height: 1.6;
            color: var(--text-primary);
            background-color: var(--background-color);
            display: flex;
            justify-content: center;
            min-height: 100vh;
            padding: 24px;
        }

        .app-container {
            width: 100%;
            max-width: var(--container-max-width);
            display: flex;
            gap: 24px;
            height: calc(100vh - 48px);
            background: var(--card-background);
            border-radius: var(--border-radius);
            box-shadow: var(--shadow);
            overflow: hidden;
        }

        /* 侧边栏样式 */
        .sidebar {
            width: var(--sidebar-width);
            background: var(--card-background);
            display: flex;
            flex-direction: column;
            border-right: 1px solid var(--border-color);
            overflow: hidden;
        }

        .sidebar-header {
            padding: 24px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            border-bottom: 1px solid var(--border-color);
        }

        .sidebar-header h2 {
            font-size: 22px;
            font-weight: 600;
            color: var(--text-primary);
        }

        .search-box {
            padding: 0 24px;
            margin: 16px 0;
        }

        .search-box input {
            width: 100%;
            padding: 10px 16px;
            border: 1px solid var(--border-color);
            border-radius: 8px;
            font-size: 14px;
            background: var(--background-color);
        }

        .search-box input:focus {
            outline: none;
            border-color: var(--primary-color);
        }

        .memo-list {
            flex: 1;
            overflow-y: auto;
            padding: 0 16px 16px 16px;
        }

        .memo-item {
            padding: 16px;
            cursor: pointer;
            transition: all 0.2s ease;
            display: flex;
            flex-direction: column;
            border-radius: 10px;
            margin-bottom: 8px;
        }

        .memo-item:hover {
            background: var(--background-color);
        }

        .memo-item.active {
            background: rgba(0, 122, 255, 0.08);
        }

        .memo-title {
            font-weight: 500;
            margin-bottom: 4px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }

        .memo-preview {
            font-size: 13px;
            color: var(--text-secondary);
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }

        .memo-meta {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-top: 8px;
            font-size: 12px;
            color: var(--text-secondary);
        }

        .memo-actions {
            display: flex;
            gap: 12px;
            opacity: 0;
            transition: opacity 0.2s;
        }

        .memo-item:hover .memo-actions {
            opacity: 1;
        }

        .memo-actions i {
            font-size: 13px;
            padding: 4px;
            border-radius: 4px;
        }

        .memo-actions i:hover {
            background: rgba(0, 0, 0, 0.06);
        }

        .add-memo-btn {
            margin: 16px 24px;
            padding: 12px;
            background: var(--primary-color);
            color: white;
            text-align: center;
            border-radius: 10px;
            cursor: pointer;
            transition: background 0.2s;
            font-weight: 500;
        }

        .add-memo-btn:hover {
            background: var(--secondary-color);
        }

        /* 主内容区域样式 */
        .main-content {
            flex: 1;
            display: flex;
            flex-direction: column;
            overflow: hidden;
        }

        .header {
            padding: 24px 32px 16px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            border-bottom: 1px solid var(--border-color);
        }

        .header-title {
            font-size: 24px;
            font-weight: 600;
        }

        .header-actions {
            display: flex;
            align-items: center;
            gap: 16px;
        }

        .status-indicator {
            display: flex;
            align-items: center;
            font-size: 14px;
            color: var(--text-secondary);
        }

        .status-dot {
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background: var(--success-color);
            margin-right: 8px;
        }

        .saving {
            background: var(--warning-color);
        }

        .error {
            background: var(--error-color);
        }

        .view-toggle {
            display: flex;
            background: var(--background-color);
            border-radius: 8px;
            overflow: hidden;
            padding: 2px;
        }

        .view-toggle-btn {
            padding: 6px 12px;
            background: none;
            border: none;
            cursor: pointer;
            font-size: 13px;
            border-radius: 6px;
            transition: background 0.2s;
        }

        .view-toggle-btn.active {
            background: white;
            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
        }

        /* 编辑器区域样式 */
        .editor-container {
            flex: 1;
            display: flex;
            overflow: hidden;
        }

        .editor-pane {
            flex: 1;
            padding: 24px 32px;
            overflow-y: auto;
            display: flex;
            flex-direction: column;
        }

        .editor-pane.full-width {
            width: 100%;
        }

        .editor-pane.half-width {
            width: 50%;
            border-right: 1px solid var(--border-color);
        }

        .preview-pane {
            flex: 1;
            padding: 24px 32px;
            overflow-y: auto;
            display: none;
            background: var(--card-background);
        }

        .preview-pane.visible {
            display: block;
        }

        /* Markdown预览样式 */
        .markdown-preview {
            font-size: 16px;
            line-height: 1.7;
        }

        .markdown-preview h1 {
            font-size: 28px;
            margin-top: 24px;
            margin-bottom: 16px;
            padding-bottom: 10px;
            border-bottom: 1px solid var(--border-color);
            font-weight: 600;
        }

        .markdown-preview h2 {
            font-size: 24px;
            margin-top: 24px;
            margin-bottom: 12px;
            font-weight: 600;
        }

        .markdown-preview h3 {
            font-size: 20px;
            margin-top: 20px;
            margin-bottom: 10px;
            font-weight: 600;
        }

        .markdown-preview p {
            margin-bottom: 16px;
        }

        .markdown-preview ul, .markdown-preview ol {
            margin-bottom: 16px;
            padding-left: 24px;
        }

        .markdown-preview blockquote {
            border-left: 4px solid var(--primary-color);
            padding-left: 16px;
            color: var(--text-secondary);
            margin-bottom: 16px;
            font-style: italic;
        }

        .markdown-preview code {
            background: var(--background-color);
            padding: 2px 6px;
            border-radius: 6px;
            font-family: 'SF Mono', Monaco, Inconsolata, 'Roboto Mono', Consolas, 'Courier New', monospace;
            font-size: 14px;
        }

        .markdown-preview pre {
            background: var(--background-color);
            padding: 16px;
            border-radius: 8px;
            overflow: auto;
            margin-bottom: 16px;
        }

        .markdown-preview pre code {
            background: none;
            padding: 0;
        }

        .markdown-preview table {
            border-collapse: collapse;
            width: 100%;
            margin-bottom: 16px;
        }

        .markdown-preview table, .markdown-preview th, .markdown-preview td {
            border: 1px solid var(--border-color);
        }

        .markdown-preview th, .markdown-preview td {
            padding: 8px 12px;
        }

        .markdown-preview th {
            background: #f8f9fa;
        }

        /* 底部操作栏样式 */
        .editor-footer {
            padding: 16px 32px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            border-top: 1px solid var(--border-color);
        }

        .last-saved {
            font-size: 13px;
            color: var(--text-secondary);
        }

        .footer-actions {
            display: flex;
            gap: 12px;
        }

        .footer-actions button {
            padding: 8px 16px;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            font-size: 14px;
            transition: all 0.2s;
            font-weight: 500;
        }

        .btn-primary {
            background: var(--primary-color);
            color: white;
        }

        .btn-primary:hover {
            background: var(--secondary-color);
        }

        .btn-secondary {
            background: var(--background-color);
            color: var(--text-primary);
        }

        .btn-secondary:hover {
            background: #E4E4E7;
        }

        /* EasyMDE自定义样式 */
        .EasyMDEContainer {
            flex: 1;
            display: flex;
            flex-direction: column;
        }

        .EasyMDEContainer .CodeMirror {
            flex: 1;
            font-size: 16px;
            border: none;
            padding: 0;
            font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
        }

        .EasyMDEContainer .editor-toolbar {
            border: none;
            background: transparent;
            padding: 0 0 16px 0;
        }

        .EasyMDEContainer .editor-toolbar button {
            border-radius: 6px;
        }

        .EasyMDEContainer .editor-toolbar button:hover {
            background: var(--background-color);
        }

        /* 响应式设计 */
        @media (max-width: 1024px) {
            .app-container {
                flex-direction: column;
                height: auto;
            }

            .sidebar {
                width: 100%;
                max-height: 300px;
                border-right: none;
                border-bottom: 1px solid var(--border-color);
            }

            .editor-pane.half-width {
                width: 100%;
                border-right: none;
            }

            .preview-pane.visible {
                width: 100%;
            }

            .editor-container {
                flex-direction: column;
            }
        }

        @media (max-width: 768px) {
            body {
                padding: 16px;
            }

            .header, .editor-pane, .preview-pane {
                padding: 16px;
            }

            .header-title {
                font-size: 20px;
            }

            .header-actions {
                flex-direction: column;
                align-items: flex-end;
                gap: 8px;
            }

            .view-toggle {
                order: -1;
            }
        }

        /* 加载指示器 */
        .loader {
            display: inline-block;
            width: 16px;
            height: 16px;
            border: 2px solid #f3f3f3;
            border-top: 2px solid var(--primary-color);
            border-radius: 50%;
            animation: spin 1s linear infinite;
            margin-right: 8px;
        }

        @keyframes spin {
            0% {
                transform: rotate(0deg);
            }
            100% {
                transform: rotate(360deg);
            }
        }

        /* 标题编辑模态框 */
        .modal-overlay {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0, 0, 0, 0.5);
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 1000;
        }

        .modal {
            background: white;
            padding: 24px;
            border-radius: 12px;
            width: 90%;
            max-width: 400px;
            box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
        }

        .modal h3 {
            margin-bottom: 16px;
            font-weight: 600;
        }

        .modal-input {
            width: 100%;
            padding: 12px;
            border: 1px solid var(--border-color);
            border-radius: 8px;
            font-size: 16px;
            margin-bottom: 16px;
        }

        .modal-input:focus {
            outline: none;
            border-color: var(--primary-color);
        }

        .modal-actions {
            display: flex;
            justify-content: flex-end;
            gap: 12px;
        }

        .modal-btn {
            padding: 8px 16px;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            font-weight: 500;
        }

        .modal-btn-primary {
            background: var(--primary-color);
            color: white;
        }

        .modal-btn-secondary {
            background: var(--background-color);
            color: var(--text-primary);
        }

        /* 字数统计样式 */
        .word-count {
            position: absolute;
            right: 20px;
            bottom: 20px;
            background: rgba(255, 255, 255, 0.9);
            padding: 4px 8px;
            border-radius: 4px;
            font-size: 12px;
            color: var(--text-secondary);
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
        }

        /* 表情选择器样式 */
        .emoji-picker {
            position: absolute;
            background: white;
            border: 1px solid var(--border-color);
            border-radius: 8px;
            padding: 10px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
            z-index: 100;
            display: none;
            max-width: 300px;
            max-height: 200px;
            overflow-y: auto;
        }

        .emoji-picker.visible {
            display: grid;
            grid-template-columns: repeat(8, 1fr);
            gap: 5px;
        }

        .emoji-item {
            font-size: 18px;
            padding: 5px;
            cursor: pointer;
            text-align: center;
            border-radius: 4px;
        }

        .emoji-item:hover {
            background: var(--background-color);
        }
    </style>
</head>
<body>
<div class="app-container">
    <!-- 侧边栏 -->
    <div class="sidebar">
        <div class="sidebar-header">
            <h2>备忘录</h2>
            <i class="fas fa-search" style="color: var(--text-secondary);"></i>
        </div>

        <div class="search-box">
            <input type="text" placeholder="搜索备忘录..." id="search-input">
        </div>

        <div class="memo-list" id="memo-list">
            <!-- 备忘录列表将通过AJAX加载 -->
            <div class="memo-item" style="justify-content: center; align-items: center; height: 100px;">
                <div class="loader"></div>
                <span>加载中...</span>
            </div>
        </div>

        <div class="add-memo-btn" id="add-memo-btn">
            <i class="fas fa-plus"></i> 新建备忘录
        </div>
    </div>

    <!-- 主内容区域 -->
    <div class="main-content">
        <div class="header">
            <div class="header-title" id="memo-title"></div>
            <div class="header-actions">
                <div class="status-indicator">
                    <div class="status-dot" id="status-dot"></div>
                    <span id="status-text">就绪</span>
                </div>
                <div class="view-toggle">
                    <button class="view-toggle-btn" id="edit-view-btn">
                        <i class="fas fa-edit"></i>
                    </button>
                    <button class="view-toggle-btn" id="split-view-btn">
                        <i class="fas fa-columns"></i>
                    </button>
                    <button class="view-toggle-btn active" id="preview-view-btn">
                        <i class="fas fa-eye"></i>
                    </button>
                </div>
            </div>
        </div>

        <div class="editor-container">
            <div class="editor-pane full-width" id="editor-pane" style="display: none;">
                    <textarea id="markdown-editor"># 欢迎使用备忘录

请从左侧选择一个备忘录或创建一个新备忘录开始编辑。</textarea>
            </div>
            <div class="preview-pane visible" id="preview-pane">
                <div class="markdown-preview" id="markdown-preview"></div>
            </div>
        </div>

        <div class="editor-footer">
            <div class="last-saved">
                最后保存: <span id="last-saved-time">-</span>
            </div>
            <div class="footer-actions" style="align-items: center">
                <button class="btn-outline-light" id="return-user-index">
                    <a href="/" style="color: #aaaaaa"><i class="fa-solid fa-house"></i></a>
                </button>
                <button class="btn-secondary" id="export-btn">
                    <i class="fas fa-download"></i> 导出
                </button>
                <button class="btn-primary" id="save-btn">
                    <i class="fas fa-save"></i> 保存
                </button>
            </div>
        </div>
    </div>
</div>

<!-- 表情选择器 -->
<div class="emoji-picker" id="emoji-picker">
    <!-- 表情将通过JavaScript动态添加 -->
</div>

<script>
    // 初始化变量
    let currentView = 'preview'; // 默认设置为预览模式
    let saveTimeout;
    let currentMemoId = null;
    let memos = [];
    let editingMemoId = null;
    let currentModal = null;
    let escKeyHandler = null;

    // 常用表情列表
    const commonEmojis = [
        '😀', '😃', '😄', '😁', '😆', '😅', '😂', '🤣', '😊', '😇',
        '🙂', '🙃', '😉', '😌', '😍', '🥰', '😘', '😗', '😙', '😚',
        '👍', '👎', '❤️', '🔥', '⭐', '✨', '🎉', '💯', '🤔', '🙄',
        '😎', '🥳', '😢', '😭', '😤', '😡', '🤬', '🤯', '😴', '🥱'
    ];

    // 配置marked
    marked.setOptions({
        highlight: function (code, lang) {
            // 如果没有highlight.js，直接返回代码
            if (!window.hljs) return code;

            if (lang && window.hljs.getLanguage(lang)) {
                try {
                    return window.hljs.highlight(code, {language: lang}).value;
                } catch (e) {
                    console.error('代码高亮错误:', e);
                }
            }

            try {
                return window.hljs.highlightAuto(code).value;
            } catch (e) {
                console.error('自动代码高亮错误:', e);
                return code;
            }
        }
    });

    // 获取DOM元素
    const statusDot = document.getElementById('status-dot');
    const statusText = document.getElementById('status-text');
    const lastSavedTime = document.getElementById('last-saved-time');
    const markdownPreview = document.getElementById('markdown-preview');
    const exportBtn = document.getElementById('export-btn');
    const saveBtn = document.getElementById('save-btn');
    const editorPane = document.getElementById('editor-pane');
    const previewPane = document.getElementById('preview-pane');
    const editViewBtn = document.getElementById('edit-view-btn');
    const splitViewBtn = document.getElementById('split-view-btn');
    const previewViewBtn = document.getElementById('preview-view-btn');
    const memoList = document.getElementById('memo-list');
    const addMemoBtn = document.getElementById('add-memo-btn');
    const searchInput = document.getElementById('search-input');
    const memoTitle = document.getElementById('memo-title');
    const emojiPicker = document.getElementById('emoji-picker');

    // 初始化Markdown编辑器
    const easyMDE = new EasyMDE({
        element: document.getElementById('markdown-editor'),
        autoDownloadFontAwesome: false,
        spellChecker: false,
        status: false,
        autosave: {
            enabled: false, // 我们将实现自己的自动保存
        },
        renderingConfig: {
            codeSyntaxHighlighting: true,
        },
        toolbar: [
            'bold', 'italic', 'heading', '|',
            'code', 'quote', 'unordered-list', 'ordered-list', '|',
            'link', 'image', '|',
            {
                name: 'table',
                action: function insertTable(editor) {
                    const cm = editor.codemirror;
                    const cursor = cm.getCursor();
                    const table =
                        `| 标题1 | 标题2 | 标题3 |
|-------|-------|-------|
| 内容1 | 内容2 | 内容3 |
| 内容4 | 内容5 | 内容6 |`;
                    cm.replaceRange(table, cursor);
                },
                className: 'fa fa-table',
                title: '插入表格',
            },
            {
                name: 'tasklist',
                action: function insertTaskList(editor) {
                    const cm = editor.codemirror;
                    const cursor = cm.getCursor();
                    const taskList =
                        `- [ ] 任务1
- [ ] 任务2
- [ ] 任务3`;
                    cm.replaceRange(taskList, cursor);
                },
                className: 'fa fa-tasks',
                title: '插入任务列表',
            },
            {
                name: 'timestamp',
                action: function insertTimestamp(editor) {
                    const cm = editor.codemirror;
                    const cursor = cm.getCursor();
                    const now = new Date();
                    const timestamp = now.toLocaleString('zh-CN');
                    cm.replaceRange(timestamp, cursor);
                },
                className: 'fa fa-clock',
                title: '插入时间戳',
            },
            {
                name: 'code-template',
                action: function insertCodeTemplate(editor) {
                    const cm = editor.codemirror;
                    const cursor = cm.getCursor();
                    const codeTemplate =
                        "```javascript\nfunction example() {\n  console.log('Hello, World!');\n}\n```";
                    cm.replaceRange(codeTemplate, cursor);
                },
                className: 'fa fa-code',
                title: '插入代码模板',
            },
            {
                name: 'emoji',
                action: function toggleEmojiPicker(editor) {
                    const rect = editor.toolbarElements.emoji.getBoundingClientRect();
                    emojiPicker.style.top = (rect.bottom + window.scrollY) + 'px';
                    emojiPicker.style.left = (rect.left + window.scrollX) + 'px';
                    emojiPicker.classList.toggle('visible');
                },
                className: 'fa fa-smile',
                title: '插入表情',
            },
            {
                name: 'clean',
                action: function cleanText(editor) {
                    const cm = editor.codemirror;
                    const selection = cm.getSelection();
                    if (selection) {
                        // 移除多余的空白字符
                        const cleaned = selection.replace(/\s+/g, ' ').trim();
                        cm.replaceSelection(cleaned);
                    } else {
                        // 清理整个文档
                        const content = cm.getValue();
                        const cleaned = content.replace(/[^\S\n]+/g, ' ') // 替换多个空格为一个
                            .replace(/\n{3,}/g, '\n\n'); // 替换多个换行为两个
                        cm.setValue(cleaned);
                    }
                },
                className: 'fa fa-broom',
                title: '清理文本格式',
            },
            {
                name: 'wordcount',
                action: function showWordCount(editor) {
                    const cm = editor.codemirror;
                    const content = cm.getValue();
                    const wordCount = content.trim() === '' ? 0 : content.trim().split(/\s+/).length;
                    const charCount = content.length;

                    alert(`字数统计:\n字符数: ${charCount}\n单词数: ${wordCount}`);
                },
                className: 'fa fa-font',
                title: '字数统计',
            },
            {
                name: 'toc',
                action: function insertTableOfContents(editor) {
                    const cm = editor.codemirror;
                    const content = cm.getValue();
                    const lines = content.split('\n');
                    let toc = '# 目录\n\n';

                    lines.forEach(line => {
                        if (line.startsWith('## ')) {
                            const title = line.substring(3).trim();
                            const anchor = title.toLowerCase().replace(/[^\w]+/g, '-');
                            toc += `- [${title}](#${anchor})\n`;
                        } else if (line.startsWith('### ')) {
                            const title = line.substring(4).trim();
                            const anchor = title.toLowerCase().replace(/[^\w]+/g, '-');
                            toc += `  - [${title}](#${anchor})\n`;
                        }
                    });

                    cm.setValue(toc + '\n\n' + content);
                },
                className: 'fa fa-list',
                title: '生成目录',
            },
            {
                name: 'guide',
                action: function openGuide() {
                    window.open('/memos/help', '_blank');
                },
                className: 'fa fa-info-circle',
                title: 'Markdown语法指南',
            }
        ]
    });

    // 初始化表情选择器
    function initEmojiPicker() {
        const emojiContainer = document.getElementById('emoji-picker');
        commonEmojis.forEach(emoji => {
            const emojiElement = document.createElement('div');
            emojiElement.className = 'emoji-item';
            emojiElement.textContent = emoji;
            emojiElement.addEventListener('click', () => {
                const cm = easyMDE.codemirror;
                const cursor = cm.getCursor();
                cm.replaceRange(emoji, cursor);
                emojiPicker.classList.remove('visible');
                updatePreview(); // 更新预览
            });
            emojiContainer.appendChild(emojiElement);
        });

        // 点击页面其他区域关闭表情选择器
        document.addEventListener('click', (e) => {
            if (emojiPicker.classList.contains('visible') &&
                !e.target.closest('.emoji-picker') &&
                !e.target.closest('.editor-toolbar button[title="插入表情"]')) {
                emojiPicker.classList.remove('visible');
            }
        });
    }

    // 更新预览 - 统一使用marked库渲染
    function updatePreview() {
        const content = easyMDE.value();
        try {
            const sanitizedContent = DOMPurify.sanitize(marked.parse(content));
            markdownPreview.innerHTML = sanitizedContent;

            // 为预览中的标题添加ID以便目录跳转
            document.querySelectorAll('.markdown-preview h1, .markdown-preview h2, .markdown-preview h3').forEach(heading => {
                if (!heading.id) {
                    heading.id = heading.textContent.toLowerCase().replace(/[^\w]+/g, '-');
                }
            });
        } catch (error) {
            console.error('Markdown解析错误:', error);
            markdownPreview.innerHTML = '<p>预览解析错误</p>';
        }
    }

    // 初始更新预览
    updatePreview();

    // 设置状态
    function setStatus(status, text) {
        statusDot.className = 'status-dot ' + status;
        statusText.textContent = text;
    }

    // AJAX请求函数
    async function apiRequest(url, method = 'GET', data = null) {
        setStatus('saving', '请求中...');

        const options = {
            method: method,
            headers: {
                'Content-Type': 'application/json',
            },
        };

        if (data) {
            options.body = JSON.stringify(data);
        }

        try {
            const response = await fetch(url, options);

            // 检查HTTP状态码
            if (!response.ok) {
                const errorData = await response.json().catch(() => ({}));
                throw new Error(errorData.error || `服务器错误: ${response.status}`);
            }

            const result = await response.json();
            setStatus('', '就绪');
            return result;
        } catch (error) {
            console.error('API请求错误:', error);
            setStatus('error', '错误: ' + error.message);
            // 3秒后恢复状态
            setTimeout(() => setStatus('', '就绪'), 3000);
            throw error;
        }
    }

    // HTML转义函数
    function escapeHtml(text) {
        if (!text) return '';
        const div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }

    // 日期格式化
    function formatDate(dateString) {
        if (!dateString) return '未知时间';

        try {
            const date = new Date(dateString);
            const now = new Date();
            const diffTime = Math.abs(now - date);
            const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));

            if (diffDays === 0) {
                return '今天 ' + date.toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'});
            } else if (diffDays === 1) {
                return '昨天 ' + date.toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'});
            } else if (diffDays < 7) {
                return diffDays + '天前';
            } else {
                return date.toLocaleDateString();
            }
        } catch (error) {
            console.error('日期格式化错误:', error);
            return '未知时间';
        }
    }

    // 从内容中提取标题
    function extractTitle(content) {
        if (!content) return '无标题';

        // 查找第一个标题
        const match = content.match(/^#\s+(.+)$/m);
        return match ? match[1].trim() : '无标题';
    }

    // 从内容中提取预览
    function extractPreview(content) {
        if (!content) return '无内容';

        // 移除标题行和代码块
        let text = content.replace(/^#\s+.+$/m, '')
            .replace(/```[\s\S]*?```/g, '')
            .replace(/`[^`]*`/g, '');

        // 获取第一段有意义的内容
        const lines = text.split('\n');
        for (let line of lines) {
            line = line.trim();
            if (line && !line.startsWith('>') && !line.startsWith('-') && !line.startsWith('*') && !line.startsWith('+')) {
                return line.length > 50 ? line.substring(0, 50) + '...' : line;
            }
        }

        return '无内容';
    }

    // 加载备忘录列表
    async function loadMemos() {
        try {
            const data = await apiRequest('/api/memos');
            memos = data;
            renderMemos(memos);
        } catch (error) {
            memoList.innerHTML = '<div class="memo-item" style="color: var(--error-color);">加载失败: ' + error.message + '</div>';
        }
    }

    // 渲染备忘录列表
    function renderMemos(memosToRender) {
        if (!memosToRender || memosToRender.length === 0) {
            memoList.innerHTML = '<div class="memo-item" style="justify-content: center; color: var(--text-secondary);">暂无备忘录</div>';
            return;
        }

        memoList.innerHTML = memosToRender.map(memo => `
                <div class="memo-item ${currentMemoId == memo.id ? 'active' : ''}" data-id="${memo.id}">
                    <div class="memo-title">${escapeHtml(memo.title)}</div>
                    <div class="memo-preview">${escapeHtml(memo.preview || '无内容')}</div>
                    <div class="memo-meta">
                        <span>${formatDate(memo.updatedtime)}</span>
                        <div class="memo-actions">
                            <i class="fas fa-pencil-alt" data-action="edit"></i>
                            <i class="fas fa-trash-alt" data-action="delete"></i>
                        </div>
                    </div>
                </div>
            `).join('');
    }

    // 加载单个备忘录
    async function loadMemo(id) {
        try {
            setStatus('saving', '加载中...');
            const memo = await apiRequest(`/api/memos/${id}`);

            currentMemoId = id;
            easyMDE.value(memo.content);
            // memoTitle.textContent = memo.title;
            memoTitle.textContent = '';
            updatePreview();

            // 更新最后保存时间
            lastSavedTime.textContent = formatDate(memo.updatedtime);

            // 更新活动备忘录项
            document.querySelectorAll('.memo-item').forEach(item => {
                item.classList.toggle('active', item.getAttribute('data-id') == id);
            });

            setStatus('', '已加载');
        } catch (error) {
            console.error('加载备忘录失败:', error);
        }
    }

    // 保存备忘录
    async function saveMemo() {
        if (!currentMemoId) {
            alert('请先选择一个备忘录');
            return;
        }

        try {
            const content = easyMDE.value();
            const title = extractTitle(content);

            const updatedMemo = await apiRequest(`/api/memos/${currentMemoId}`, 'PUT', {
                title: title,
                content: content
            });

            // 更新最后保存时间
            lastSavedTime.textContent = formatDate(updatedMemo.updatedtime);

            // 更新备忘录列表中的标题和预览
            const memoIndex = memos.findIndex(m => m.id == currentMemoId);
            if (memoIndex !== -1) {
                memos[memoIndex].title = title;
                memos[memoIndex].preview = extractPreview(content);
                memos[memoIndex].updatedtime = updatedMemo.updatedtime;
                renderMemos(memos);
            }

            setStatus('', '已保存');
            return updatedMemo;
        } catch (error) {
            console.error('保存备忘录失败:', error);
            throw error;
        }
    }

    // 创建新备忘录
    async function createMemo() {
        try {
            const newMemo = await apiRequest('/api/memos', 'POST', {
                title: '新备忘录',
                content: '# 新备忘录\n\n开始编写您的内容...'
            });

            // 添加到备忘录列表
            memos.unshift(newMemo);
            renderMemos(memos);

            // 加载新备忘录
            loadMemo(newMemo.id);

            return newMemo;
        } catch (error) {
            console.error('创建备忘录失败:', error);
            throw error;
        }
    }

    // 删除备忘录
    async function deleteMemo(id) {
        if (!confirm('确定要删除这个备忘录吗？此操作不可撤销。')) {
            return;
        }

        try {
            await apiRequest(`/api/memos/${id}`, 'DELETE');

            // 从列表中移除
            memos = memos.filter(m => m.id != id);
            renderMemos(memos);

            // 如果删除的是当前备忘录，清空编辑器
            if (currentMemoId == id) {
                currentMemoId = null;
                easyMDE.value('');
                memoTitle.textContent = '选择或创建备忘录';
                updatePreview();
                lastSavedTime.textContent = '-';
            }
        } catch (error) {
            console.error('删除备忘录失败:', error);
        }
    }

    // 关闭当前模态框
    function closeCurrentModal() {
        if (currentModal) {
            document.body.removeChild(currentModal);
            currentModal = null;
            editingMemoId = null;

            // 移除ESC键事件监听器
            if (escKeyHandler) {
                document.removeEventListener('keydown', escKeyHandler);
                escKeyHandler = null;
            }
        }
    }

    // 显示编辑标题模态框
    function showEditTitleModal(memoId) {
        const memo = memos.find(m => m.id == memoId);
        if (!memo) return;

        // 关闭任何已存在的模态框
        closeCurrentModal();

        editingMemoId = memoId;

        // 创建模态框
        currentModal = document.createElement('div');
        currentModal.className = 'modal-overlay';
        currentModal.innerHTML = `
                <div class="modal">
                    <h3>编辑备忘录标题</h3>
                    <input type="text" class="modal-input" value="${escapeHtml(memo.title)}" id="edit-title-input">
                    <div class="modal-actions">
                        <button class="modal-btn modal-btn-secondary" id="edit-title-cancel">取消</button>
                        <button class="modal-btn modal-btn-primary" id="edit-title-save">保存</button>
                    </div>
                </div>
            `;

        document.body.appendChild(currentModal);

        // 聚焦输入框
        setTimeout(() => {
            const input = document.getElementById('edit-title-input');
            if (input) {
                input.focus();
                input.select();
            }
        }, 100);

        // 添加事件监听 - 取消按钮
        document.getElementById('edit-title-cancel').addEventListener('click', () => {
            closeCurrentModal();
        });

        // 添加事件监听 - 保存按钮
        document.getElementById('edit-title-save').addEventListener('click', () => {
            const newTitle = document.getElementById('edit-title-input').value.trim();
            if (newTitle) {
                updateMemoTitle(memoId, newTitle);
            }
            closeCurrentModal();
        });

        // 点击遮罩层关闭
        currentModal.addEventListener('click', (e) => {
            if (e.target === currentModal) {
                closeCurrentModal();
            }
        });

        // 按ESC键关闭
        escKeyHandler = (e) => {
            if (e.key === 'Escape') {
                closeCurrentModal();
            }
        };

        document.addEventListener('keydown', escKeyHandler);
    }

    // 更新备忘录标题
    async function updateMemoTitle(id, newTitle) {
        const memo = memos.find(m => m.id == id);
        if (!memo || memo.title === newTitle) return;

        try {
            const updatedMemo = await apiRequest(`/api/memos/${id}`, 'PUT', {
                title: newTitle,
                content: memo.content
            });

            // 更新列表中的备忘录
            memo.title = newTitle;
            memo.updatedtime = updatedMemo.updatedtime;
            renderMemos(memos);

            // 如果编辑的是当前备忘录，更新右侧标题
            if (currentMemoId == id) {
                memoTitle.textContent = newTitle;

                // 如果内容中的标题也需要更新
                const content = easyMDE.value();
                const newContent = content.replace(/^#\s+.+$/m, `# ${newTitle}`);
                easyMDE.value(newContent);
                updatePreview();
            }
        } catch (error) {
            console.error('更新标题失败:', error);
        }
    }

    // 设置自动保存
    easyMDE.codemirror.on("change", () => {
        updatePreview();

        // 清除之前的超时
        clearTimeout(saveTimeout);

        // 如果没有选择备忘录，不自动保存
        if (!currentMemoId) return;

        // 设置新的保存超时
        saveTimeout = setTimeout(() => {
            saveMemo().catch(error => {
                console.error('自动保存失败:', error);
            });
        }, 2000); // 2秒后自动保存

        setStatus('saving', '编辑中...');
    });

    // 切换视图函数
    function changeView(view) {
        currentView = view;

        // 更新按钮状态
        editViewBtn.classList.toggle('active', view === 'edit');
        splitViewBtn.classList.toggle('active', view === 'split');
        previewViewBtn.classList.toggle('active', view === 'preview');

        // 更新编辑器布局
        if (view === 'edit') {
            editorPane.style.display = 'flex';
            editorPane.classList.remove('half-width');
            editorPane.classList.add('full-width');
            previewPane.classList.remove('visible');
        } else if (view === 'split') {
            editorPane.style.display = 'flex';
            editorPane.classList.remove('full-width');
            editorPane.classList.add('half-width');
            previewPane.classList.add('visible');
        } else if (view === 'preview') {
            editorPane.style.display = 'none';
            previewPane.classList.add('visible');
        }

        // 确保预览内容是最新的
        updatePreview();
    }

    // 使用事件委托处理备忘录项点击
    function handleMemoItemClick(e) {
        const memoItem = e.target.closest('.memo-item');
        if (!memoItem) return;

        const memoId = memoItem.getAttribute('data-id');
        const action = e.target.getAttribute('data-action');

        if (action === 'delete') {
            e.stopPropagation();
            deleteMemo(memoId);
        } else if (action === 'edit') {
            e.stopPropagation();
            showEditTitleModal(memoId);
        } else {
            loadMemo(memoId);
        }
    }

    // 初始化事件监听
    function initEventListeners() {
        // 视图切换按钮事件监听
        editViewBtn.addEventListener('click', () => changeView('edit'));
        splitViewBtn.addEventListener('click', () => changeView('split'));
        previewViewBtn.addEventListener('click', () => changeView('preview'));

        // 导出功能
        exportBtn.addEventListener('click', () => {
            const content = easyMDE.value();
            const blob = new Blob([content], {type: 'text/markdown'});
            const url = URL.createObjectURL(blob);

            const a = document.createElement('a');
            a.href = url;
            a.download = 'memo-' + new Date().toISOString().split('T')[0] + '.md';
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
        });

        // 手动保存按钮
        saveBtn.addEventListener('click', () => {
            clearTimeout(saveTimeout);
            saveMemo().catch(error => {
                alert('保存失败: ' + error.message);
            });
        });

        // 新建备忘录按钮
        addMemoBtn.addEventListener('click', () => {
            createMemo().catch(error => {
                alert('创建备忘录失败: ' + error.message);
            });
        });

        // 搜索功能
        searchInput.addEventListener('input', () => {
            const searchTerm = searchInput.value.toLowerCase();

            if (!searchTerm) {
                renderMemos(memos);
                return;
            }

            const filteredMemos = memos.filter(memo =>
                memo.title.toLowerCase().includes(searchTerm) ||
                (memo.preview && memo.preview.toLowerCase().includes(searchTerm)) ||
                (memo.content && memo.content.toLowerCase().includes(searchTerm))
            );

            renderMemos(filteredMemos);
        });

        // 备忘录项点击事件委托
        memoList.addEventListener('click', handleMemoItemClick);
        // 添加全局键盘快捷键监听，切换不同的编辑预览模式（右上角的）
        document.addEventListener('keydown', function (event) {

            // 你也可以定义其他不配合 Ctrl 的快捷键，例如 F2, F3, F4
            // 注意：某些功能键可能已被浏览器或系统占用
            switch (event.key) {
                case 'F2':
                    event.preventDefault();
                    changeView('edit');
                    break;
                case 'F3':
                    event.preventDefault();
                    changeView('split');
                    break;
                case 'F4':
                    event.preventDefault();
                    changeView('preview');
                    break;
                default:
                    break;
            }
        });
    }

    // 初始化应用
    async function initApp() {
        initEventListeners();
        initEmojiPicker();
        await loadMemos();
        setStatus('', '就绪');

        // 默认以预览模式打开
        changeView('preview');
    }

    // 启动应用
    initApp().catch(error => {
        console.error('应用初始化失败:', error);
        setStatus('error', '初始化失败');
    });
</script>
</body>
</html>

